<script setup>
import {onBeforeMount, reactive, ref, watchEffect} from "vue";
import {Plus} from '@element-plus/icons-vue'
import {uploadProductAPI} from "@/api/product.js";
import {randomString} from "@/utils/RandomUtils.js";
import {elErrorMessageTip, elSuccessMessageTip} from "@/utils/MessageTipUtils.js";
import {FILE_URL_FIELD_NAME, fileUploadAPI, TIP_MSG_FIELD_NAME} from "@/api/file.js";
import {addPercentageInterval, INTERVAL_FIELD_NAME} from "@/utils/FileUtils.js";
// import Vditor from "vditor";
import "vditor/src/assets/less/index.less"
import {preview} from 'vue3-image-preview';
import {getAddrSelectOptions, getProductCategoryOptions} from "@/utils/CommonDataUtil.js";
// import Editor from '@tinymce/tinymce-vue'
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import {onBeforeUnmount, shallowRef} from 'vue'
import {Editor, Toolbar} from '@wangeditor/editor-for-vue'

// ***********
// * 输入限制 *
// ***********
const env = import.meta.env
const PRODUCT_TITLE_MAX_LEN = env.VITE_PRODUCT_TITLE_MAX_LEN
const PRODUCT_ISBN_MAX_LEN = env.VITE_PRODUCT_ISBN_MAX_LEN
const PRODUCT_ADDRESS_MAX_LEN = env.VITE_PRODUCT_ADDRESS_MAX_LEN
const PRODUCT_LABEL_NAME_MAX_LEN = env.VITE_PRODUCT_LABEL_NAME_MAX_LEN
const PRODUCT_PARAM_NAME_MAX_LEN = env.VITE_PRODUCT_PARAM_NAME_MAX_LEN
const PRODUCT_PARAM_VAL_MAX_LEN = env.VITE_PRODUCT_PARAM_VAL_MAX_LEN
const PRODUCT_OPTIOON_NAME_MAX_LEN = env.VITE_PRODUCT_OPTIOON_NAME_MAX_LEN

// ***********
// * 商品编号 *
// ***********
const code = ref('')

// ***********
// * 商品标题 *
// ***********
const title = ref('')

// ***********
// * 商品分类 *
// ***********
const productCategory = ref('')
const productCategoryOptions = ref('')
const productCategorySub = ref('')
const productCategorySubDisabled = ref(false)
const productCategorySubOptions = ref('')
const productCategoryAll = ref([])

// ***********
// * 商品运费 *
// ***********
const freight = ref(0)

// 获取中国区县信息
const chineseAllDistinguish = ref([]);

// *********
// * 发货地 *
// *********
const provinceSelectVal = ref('')
const provinceSelectOptions = ref([])
const citySelectVal = ref('')
const citySelectDisabled = ref(false)
const citySelectOptions = ref([])
const distinguishSelectVal = ref('')
const distinguishSelectDisabled = ref(false)
const distinguishSelectOptions = ref([])
// 请输入商品发货详细地址
const address = ref('')
onBeforeMount(async () => {
  // 获取省市区数据
  await getAddrSelectOptions(chineseAllDistinguish, provinceSelectOptions)
  // 获取分类数据
  await getProductCategoryOptions(productCategoryAll, productCategoryOptions)
})
const productCategoryChange = () => {
  if (productCategory.value !== '' && productCategory.value !== null) {
    productCategorySub.value = ''
    productCategorySubOptions.value = productCategoryAll.value.find(
        item => item.id === productCategory.value
    ).subs.map(
        item => ({value: item.id, label: item.name})
    )
  }
}
const provinceSelectValChange = () => {
  if (provinceSelectVal.value.length > 0) {
    citySelectVal.value = ''
    distinguishSelectVal.value = ''
    citySelectOptions.value = chineseAllDistinguish.value.find(
        item => item.name === provinceSelectVal.value
    ).districtList.map(
        item => ({value: item.name, label: item.name})
    )
  }
}
const citySelectValChange = () => {
  if (citySelectVal.value.length > 0) {
    distinguishSelectVal.value = ''
    distinguishSelectOptions.value = chineseAllDistinguish.value.find(
        item => item.name === provinceSelectVal.value
    ).districtList.find(
        item => item.name === citySelectVal.value
    ).districtList.map(
        item => ({value: item.name, label: item.name})
    )
  }
}
watchEffect(() => {
  if (provinceSelectVal.value.length > 0) {
    citySelectDisabled.value = false
  } else {
    citySelectDisabled.value = true
    distinguishSelectDisabled.value = true
  }
  if (citySelectVal.value.length > 0) {
    distinguishSelectDisabled.value = false
  } else {
    distinguishSelectDisabled.value = true
  }
  if (productCategory.value !== '' && productCategory.value !== null) {
    productCategorySubDisabled.value = false
  } else {
    productCategorySubDisabled.value = true
  }
})

// ***********
// * 商品图片 *
// ***********
const productImgList = ref([])
// 商品图片索引
let productImgIdx = 0
const imgUpload = async (file, fileList) => {
  file = reactive(file)
  fileList.value.push(file)
  file.status = 'uploading'
  file['idx'] = productImgIdx++
  // 文件上传进度计时器
  addPercentageInterval(file)
  // 文件上传
  const res = await fileUploadAPI(file.raw)
  if (res.status) {
    // 成功
    // 清除计时器
    clearInterval(file[INTERVAL_FIELD_NAME])
    elSuccessMessageTip(res[TIP_MSG_FIELD_NAME])
    file.status = 'success'
    file.percentage = 100
    file.url = res[FILE_URL_FIELD_NAME]
  } else {
    // 失败
    // 清除计时器
    clearInterval(file[INTERVAL_FIELD_NAME])
    elErrorMessageTip(res[TIP_MSG_FIELD_NAME])
    file.status = 'fail'
  }
}
// 商品图片上传
const productImgUpload = (file) => {
  imgUpload(file, productImgList)
}
// 图片预览
const productImgPreview = (img) => {
  const previewImgIdx = img.idx
  preview({images: productImgList.value, index: productImgIdx})
}

// ***********
// * 商品选项 *
// ***********
// 商品选项个数
const productOptionCnt = ref(0)
// 上一次商品选项个数
const productOptionCntTemp = ref(0)
// 商品选项
const productOptions = ref([])
// 商品选项随机 id 长度
const productOptionIdLen = ref(10)
// 商品选项步进器增加与删除
const productOptionCntChange = (val) => {
  if (val > productOptionCntTemp.value) {
    const cnt = val - productOptionCntTemp.value
    for (let i = 0; i < cnt; i++) {
      productOptions.value.push({
        id: randomString(productOptionIdLen.value),
        name: '',
        price: 0,
        stock: 0,
        img: ''
      })
    }
  }
  if (val < productOptionCntTemp.value) {
    const cnt = productOptionCntTemp.value - val
    for (let i = 0; i < cnt; i++) {
      productOptions.value.pop()
    }
  }
  productOptionCntTemp.value = val
}
// 商品选项图片上传
const productOptionImgListTemp = ref([])
const productOptionImgList = ref([])
watchEffect(() => {
  if (productOptionImgListTemp.value.length <= 0) return
  productOptionImgList.value = productOptionImgListTemp.value.map(
      item => item?.url
  )
})
const productOptionImgUpload = async (file) => {
  imgUpload(file, productOptionImgListTemp)
}
// 商品选项指定项删除
const delProductOptionItem = (idx) => {
  productOptions.value.splice(idx, 1)
  productOptionImgListTemp.value.splice(idx, 1)
  productOptionImgList.value.splice(idx, 1)
  productOptionCnt.value = productOptions.value.length
  productOptionCntTemp.value = productOptions.value.length
}

// ***********
// * 商品参数 *
// ***********
// 商品参数个数
const productParamCnt = ref(0)
// 上一次商品参数个数
const productParamCntTemp = ref(0)
// 商品参数
const productParams = ref([])
// 商品参数随机 id 长度
const productParamIdLen = ref(10)
// 商品参数步进器增加与删除
const productParamCntChange = (val) => {
  if (val > productParamCntTemp.value) {
    const cnt = val - productParamCntTemp.value
    for (let i = 0; i < cnt; i++) {
      productParams.value.push({
        id: randomString(productParamIdLen.value),
        name: '',
        val: ''
      })
    }
  }
  if (val < productParamCntTemp.value) {
    const cnt = productParamCntTemp.value - val
    for (let i = 0; i < cnt; i++) {
      productParams.value.pop()
    }
  }
  productParamCntTemp.value = val
}
// 商品参数指定项删除
const delProductParamItem = (idx) => {
  productParams.value.splice(idx, 1)
  productParamCnt.value = productParams.value.length
  productParamCntTemp.value = productParams.value.length
}

// ***********
// * 商品标签 *
// ***********
// 添加商品标签对话是否显示
const addProductLabelVisible = ref(false)
const showAddProductLabel = () => {
  addProductLabelVisible.value = true
}
const newProductLabelName = ref('')
const productLabelNames = ref([])
const addProductLabel = () => {
  if (newProductLabelName.value.length <= 0) {
    elErrorMessageTip("请先完成商品标签名称的输入")
    return
  }
  if (productLabelNames.value.indexOf(newProductLabelName.value) !== -1) {
    elErrorMessageTip("商品标签名称已存在")
    return
  }
  productLabelNames.value.push(newProductLabelName.value)
  newProductLabelName.value = ''
}
const delProductLabel = (idx) => {
  productLabelNames.value.splice(idx, 1)
}

// ***********
// * 商品描述 *
// ***********
// 编辑器内容
const vditorContent_md = ref('')
const vditorContent_html = ref('')
// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef()
const toolbarConfig = {}
const editorConfig = {
  placeholder: '请输入商品描述...',
  MENU_CONF: {
    uploadImage: {
      // server: '/api/upload',
      // 自定义上传
      async customUpload(file, insertFn) {                   // JS 语法
        // file 即选中的文件
        console.log(file)
        // 自己实现上传，并得到图片 url alt href
        const res = await fileUploadAPI(file)
        if (res.status) {
          // 成功
          elSuccessMessageTip(res[TIP_MSG_FIELD_NAME])
          // 文件在线访问路径
          const fileUrl = res[FILE_URL_FIELD_NAME]
          // 保存图片在线访问路径
          // console.log(fileUrl)
          // 最后插入图片
          insertFn(fileUrl, file.name, '')
        } else {
          // 失败
          elErrorMessageTip(res[TIP_MSG_FIELD_NAME] + file.name)
          // 编辑器中插入图片上传失败
          // 最后插入图片
          insertFn('', '图片上传失败', '')
        }
        
      }
    }
  }
}
// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})
const handleCreated = (editor) => {
  editorRef.value = editor // 记录 editor 实例，重要！
}

// 清空商品信息
const clear = () => {
  code.value = ''
  title.value = ''
  productCategory.value = ''
  productCategorySub.value = ''
  freight.value = 0
  provinceSelectVal.value = ''
  citySelectVal.value = ''
  distinguishSelectVal.value = ''
  address.value = ''
  productImgList.value = []
  productImgIdx = 0
  productOptionCntChange(0)
  productOptionCnt.value = 0
  productOptions.value = []
  productOptionImgList.value = []
  productOptionImgListTemp.value = []
  productParamCntChange(0)
  productParamCnt.value = 0
  productParams.value = []
  newProductLabelName.value = ''
  productLabelNames.value = []
  vditorContent_md.value = ''
  vditorContent_html.value = ''
  // vditorPreviewImgUrl.value = ''
  // vditorPreviewImgList.value = []
  // vditor.setValue("")
}

// 商品上传
const uploadProduct = async () => {
  // 商品选项的图片赋值
  for (let i = 0; i < productOptions.value.length; i++) {
    if (productOptionImgList.value[i]) productOptions.value[i].img = productOptionImgList.value[i]
    productOptions.value[i].id = null
  }
  // 商品图片列表
  const productImgs = productImgList.value.map(item => item?.url)
  // 商品参数
  for (let i = 0; i < productParams.value.length; i++) {
    productParams.value[i].id = null
  }
  // 上传商品
  const res = await uploadProductAPI(
      title.value, productCategory.value, productCategorySub.value, freight.value,
      provinceSelectVal.value + '/' + citySelectVal.value + '/' + distinguishSelectVal.value, address.value,
      productImgs, productOptions.value, productLabelNames.value, productParams.value,
      vditorContent_html.value, vditorContent_html.value, code.value
  )
  if (res) clear()
}


</script>

<template>
  <div class="add-product min-w-max flex justify-center items-start">
    <div class="fixed top-20 right-10 glass-container p-4 flex flex-col justify-center items-stretch">
      <div>
        <el-button @click="clear" type="warning" plain>清空商品信息</el-button>
      </div>
      <div>
        <el-button @click="uploadProduct" type="primary" plain>提交商品信息</el-button>
      </div>
    </div>
    <div class="form-container glass-container w-8/12 p-6 pt-10">
      <el-form label-position="right" label-width="105px">
        <el-form-item label="ISBN">
          <el-input placeholder="请输入书籍 ISBN" v-model="code" :maxlength="PRODUCT_ISBN_MAX_LEN" show-word-limit
                    clearable/>
        </el-form-item>
        <el-form-item label="商品标题">
          <el-input placeholder="请输入商品标题" v-model="title" :maxlength="PRODUCT_TITLE_MAX_LEN" show-word-limit
                    clearable/>
        </el-form-item>
        <el-form-item class="flex items-center justify-start" label="商品分类">
          <el-select v-model="productCategory" @change="productCategoryChange" placeholder="请选择一级商品分类">
            <el-option
                v-for="item in productCategoryOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
            />
          </el-select>
          <el-select v-model="productCategorySub" :disabled="productCategorySubDisabled"
                     placeholder="请选择二级商品分类">
            <el-option
                v-for="item in productCategorySubOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item class="flex items-center justify-start" label="发货地">
          <el-select v-model="provinceSelectVal" @change="provinceSelectValChange" placeholder="省/市/自治区">
            <el-option
                v-for="item in provinceSelectOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
            />
          </el-select>
          <el-select v-model="citySelectVal" @change="citySelectValChange" :disabled="citySelectDisabled"
                     placeholder="市">
            <el-option
                v-for="item in citySelectOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
            />
          </el-select>
          <el-select v-model="distinguishSelectVal" :disabled="distinguishSelectDisabled" placeholder="区/县">
            <el-option
                v-for="item in distinguishSelectOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
            />
          </el-select>
          <div class="flex-1">
            <el-input placeholder="请输入商品发货详细地址" v-model="address" :maxlength="PRODUCT_ADDRESS_MAX_LEN"
                      show-word-limit clearable/>
          </div>
        </el-form-item>
        <el-form-item label="运费">
          <el-input-number v-model="freight" :precision="2" :step="0.1" :min="0"/>
        </el-form-item>
        <el-form-item label="商品图片">
          <el-upload
              v-model:file-list="productImgList"
              list-type="picture-card"
              :auto-upload="false"
              multiple
              :on-change="productImgUpload"
              :on-preview="productImgPreview"
          >
            <el-icon>
              <Plus/>
            </el-icon>
          </el-upload>
        </el-form-item>
        <el-form-item label="商品选项">
          <div class="w-full mb-4 flex justify-start items-center">
            <el-input-number :min="0" v-model="productOptionCnt" @change="productOptionCntChange"/>
          </div>
          <div class="mb-2 flex justify-start items-start" v-for="(item, idx) in productOptions" :key="item.id">
            <div>
              <el-input placeholder="请输入选项名称" v-model="item.name" :maxlength="PRODUCT_OPTIOON_NAME_MAX_LEN"
                        show-word-limit/>
            </div>
            <div>
              <el-form-item label="选项价格">
                <el-input-number v-model="item.price" :precision="2" :step="0.1" :min="0"/>
              </el-form-item>
            </div>
            <div>
              <el-form-item label="库存数">
                <el-input-number v-model="item.stock" :min="0"/>
              </el-form-item>
            </div>
            <el-upload
                class="ml-4"
                :auto-upload="false"
                v-model:file-list="productOptionImgListTemp"
                :limit="productOptionCnt"
                :show-file-list="false"
                :on-change="productOptionImgUpload"
            >
              <el-button type="primary" plain>上传商品选项图片</el-button>
            </el-upload>
            <el-button class="ml-4" type="danger" plain @click="delProductOptionItem(idx)">删除</el-button>
          </div>
          <el-image
              class="mr-4"
              v-for="(item, idx) in productOptionImgList" :key="idx"
              style="width: 100px; height: 100px"
              :src="item"
              :zoom-rate="1.2"
              :max-scale="7"
              :min-scale="0.2"
              preview-teleported
              :preview-src-list="productOptionImgList"
              :initial-index="idx"
              fit="cover"
          />
        </el-form-item>
        <el-form-item label="商品标签">
          <div>
            <el-button type="primary" plain @click="showAddProductLabel">添加商品标签</el-button>
            <div>
              <el-tag class="mr-2 mt-4" closable type="success" effect="plain"
                      @close="delProductLabel(idx)"
                      v-for="(productLabelName, idx) in productLabelNames">{{ productLabelName }}
              </el-tag>
            </div>
            <el-dialog append-to-body v-model="addProductLabelVisible" title="添加商品标签">
              <el-form class="add-product-label" label-position="right" label-width="105px">
                <el-form-item label="商品标签名称">
                  <el-input v-model="newProductLabelName" clearable show-word-limit
                            :maxlength="PRODUCT_LABEL_NAME_MAX_LEN"
                            @keydown.enter.prevent="addProductLabel"
                  ></el-input>
                </el-form-item>
              </el-form>
              <div class="flex justify-end items-center">
                <el-button @click="addProductLabel">添加</el-button>
              </div>
            </el-dialog>
          </div>
        </el-form-item>
        <el-form-item label="商品参数">
          <div class="w-full mb-4 flex justify-start items-center">
            <el-input-number :min="0" @change="productParamCntChange" v-model="productParamCnt"/>
          </div>
          <div class="mt-2 flex justify-start items-start" v-for="(item, idx) in productParams" :key="item.id">
            <el-form-item label="商品参数名称">
              <el-input v-model="item.name" placeholder="请输入商品参数名称" :maxlength="PRODUCT_PARAM_NAME_MAX_LEN"
                        show-word-limit/>
            </el-form-item>
            <el-form-item label="商品参数说明">
              <el-input class="w-64" v-model="item.val" :maxlength="PRODUCT_PARAM_VAL_MAX_LEN"
                        placeholder="请输入商品参数说明" show-word-limit/>
            </el-form-item>
            <el-button class="ml-4" type="danger" plain @click="delProductParamItem(idx)">删除</el-button>
          </div>
        </el-form-item>
        <el-form-item class="w-full" label="商品描述">
          <div style="border: 1px solid #ccc">
            <Toolbar
                style="border-bottom: 1px solid #ccc"
                :editor="editorRef"
                :defaultConfig="toolbarConfig"
                :mode="'default'"
            />
            <Editor
                style="height: 500px; overflow-y: hidden;"
                v-model="vditorContent_html"
                :defaultConfig="editorConfig"
                :mode="'default'"
                @onCreated="handleCreated"
            />
          </div>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<style lang="scss">
.form-container {
  max-width: 88rem;
}

.vditor {
  width: 100%;
}

.add-product {
  .el-form-item__label {
    color: #f4f4f5;
    font-weight: bold;
  }
  
  .add-product-label {
    .el-form-item__label {
      color: #333;
      font-weight: normal;
    }
  }
}


</style>